﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;



public static class SpriteExtension
{
	private static Material spriteBaseMaterial;
	private static Dictionary<string, System.WeakReference> materialMap = new Dictionary<string, System.WeakReference>();

	public static void SetSprite(this Material material, Sprite sprite, Texture2D tex = null, string texName = "_MainTex")
	{
		if(tex == null)
		{
			material.SetTexture(texName, sprite.texture);
		}
		else
		{
			material.SetTexture(texName, tex);
		}
		Vector2 size = new Vector2(sprite.rect.width / sprite.texture.width, sprite.rect.height / sprite.texture.height);
		material.SetTextureScale(texName, size);
		Vector2 offset = new Vector2(sprite.rect.x / sprite.texture.width, sprite.rect.y / sprite.texture.height);
		material.SetTextureOffset(texName, offset);
	}

	public static void SetSpriteRect(this Material material, Rect rect, float texWidth, float texHeight, string paramName)
	{
		Vector4 size = new Vector4(rect.width / texWidth, rect.height / texHeight, rect.x / texWidth, rect.y / texHeight);
		material.SetVector(paramName, size);
	}

	public static Vector4 ConvertUV(Rect rect, float texWidth, float texHeight)
	{
		return new Vector4(rect.width / texWidth, rect.height / texHeight, rect.x / texWidth, rect.y / texHeight);
	}

	public static Material getBaseMaterial(bool isUi)
	{
		if(isUi)
		{
			return null;
		}
		else
		{
			if(spriteBaseMaterial == null)
			{
				GameObject obj = new GameObject();
				SpriteRenderer render = obj.AddComponent<SpriteRenderer>();
				spriteBaseMaterial = render.sharedMaterial;
				GameObject.DestroyImmediate(obj);
			}
			return spriteBaseMaterial;
		}
	}

	public static Vector2 GetPivot(this Sprite sprite)
	{
		Bounds bounds = sprite.bounds;
		float pivotX = -bounds.center.x / bounds.extents.x / 2 + 0.5f;
		float pivotY = -bounds.center.y / bounds.extents.y / 2 + 0.5f;
		return new Vector2(pivotX, pivotY);
	}

//	public static void SetController(this Animator animator, string animPath)
//	{
//		RuntimeAnimatorController controller = ResourcesEx.LoadAnimatorController(animPath);
//		animator.runtimeAnimatorController = controller;
//
//		animator.SetMaterialByAnimControllerPath(animPath);
//	}
//
//	public static void SetMaterialByAnimControllerPath(this Animator animator, string animPath)
//	{
//		#if UNITY_ANDROID
//		string spriteSheetName = "";
//		string spriteName = "";
//		ResourcesEx.parseSpritePath(animPath, ref spriteSheetName, ref spriteName);
//
//		SpriteRenderer spriteRender = animator.gameObject.GetComponent<SpriteRenderer>();
//		if(spriteRender == null)
//		{
//			return;
//		}
//
//		Material material = getMaterial(spriteSheetName, false);
//		spriteRender.sharedMaterial = material;
//		#endif
//	}
	
	public static void SetSprite(this Image image, string spritePath)
	{
		Sprite sprite = ResourcesEx.LoadSprite(spritePath);
		image.SetSprite(sprite);
	}

	public static void SetSprite(this SpriteRenderer render, string spritePath)
	{
		Sprite sprite = ResourcesEx.LoadSprite(spritePath);
		render.SetSprite(sprite);
	}

    /*
    static Material selectedMat;
    static Material spriteDefault;
    public static void SetSpriteHighLight(this SpriteRenderer render, bool isHighlight)
    {
        Material set;
        if (isHighlight)
        {
            if (selectedMat == null)
                selectedMat = new Material(Shader.Find("custom/sp_selected"));
            set = selectedMat;
        }
        else
        {
            if (spriteDefault == null)
                spriteDefault = new Material(Shader.Find("Sprites/Default"));
            set = spriteDefault;
        }
        render.material = set;
    }
     * */

//	public static void SetSprite(this Image image, ForgeConfigure config, bool showLelel=true)
//	{
//		ItemsConfigure item=ConfigureManager.Instance.GetItem(config.key);
//		if(item!=null)
//		{
//            image.SetSprite(item, showLelel);
//		}
//	}
//
//	public static void SetSprite(this Image image, ItemsConfigure config, bool showLevel=true)
//	{
//        string sign_mark = "sign";
//        RectTransform node_image = image.GetComponent<RectTransform>();
//        node_image.TryDestroyChild(sign_mark);
//        if (config == null)
//        {
//            return;
//        }
//        
//		if(config.category==(int)Msg.item_category.treasure)
//		{
//			ForgeConfigure forge=ConfigureManager.Instance.GetForgeConfigure(config.key);
//            ItemsConfigure item = ConfigureManager.Instance.GetItem(config.key);
//			if(forge!=null && item != null)
//			{
//				Sprite sprite=config.GetEquipmentType();
//                Vector2 size = new Vector2(node_image.rect.width, node_image.rect.height);
//                //sign节点
//                RectTransform sign_node = new GameObject(sign_mark).AddComponent<RectTransform>();
//                sign_node.SetParent(node_image, false);
//                sign_node.anchorMin = Vector2.zero;
//                sign_node.anchorMax = Vector2.one;
//                sign_node.offsetMin = sign_node.offsetMax = Vector2.zero;
//                RectTransform rect = null;
//                //等级  
//                if(showLevel)
//                {
//                    GameObject lvl = GameObject.Instantiate(ResourcesEx.LoadPrefab("Prefabs/jewelLevel", false)) as GameObject;
//                    Text txt_level = lvl.transform.GetComponentInChildren<Text>();
//                    txt_level.text = "Lv." + item.level;
//                    lvl.transform.SetParent(sign_node, false);
//                    rect = lvl.GetComponent<RectTransform>();
//                    rect.anchorMin = Vector2.up;
//                    rect.anchorMax = Vector2.one;
//                    rect.offsetMin = -Vector2.up * size.y * 0.3f;
//                    rect.offsetMax = Vector2.zero;
//                }
//
//				if(sprite!=null)
//				{
//                    //角标
//                    Image icon = new GameObject("icon").AddComponent<EvonyImage>();
//                    icon.transform.SetParent(sign_node, false);
//                    icon.SetSprite(sprite);
//                    rect = icon.GetComponent<RectTransform>();
//                    rect.anchorMin = Vector2.zero;
//                    rect.anchorMax = Vector2.one;
//                   // rect.offsetMin = Vector2.right * size.x * 0.4f;
//                    //rect.offsetMax = -Vector2.up * size.y * 0.4f;
//                    float width = size.x * 0.6f;
//                    float height = size.y * 0.6f;
//                    rect.SetInsetAndSizeFromParentEdge(RectTransform.Edge.Right, 0, width);
//                    rect.SetInsetAndSizeFromParentEdge(RectTransform.Edge.Bottom, 0, height);
//                    
//
//				}
//
//			}
//		}
//
//		image.SetSprite(config.GetItemIcon());
//	}
    
	public static void SetSprite(this Image image, Sprite sprite, bool isOverrideSprite = false)
	{
        if (image == null)
        {
            return;
        }

		if(isOverrideSprite)
		{	
			image.overrideSprite = sprite;
		}
		else
		{
			image.sprite = sprite;
		}

		Material oldMaterial = image.material;
		bool needSet = false;
		Material material = getMaterial(oldMaterial, sprite, true, out needSet);
		if(material != null || needSet)
		{
			image.material = material;
		}
	}

	public static void SetSprite(this SpriteRenderer render, Sprite sprite)
	{
        if (render == null)
        {
            return;
        }

		render.sprite = sprite;
		Material oldMaterial = render.sharedMaterial;
		bool needSet = false;
		Material material = getMaterial(oldMaterial, sprite, false, out needSet);

		if(material != null)
		{
			needSet = false;
			if(render.sharedMaterial.name != material.name)
			{
				if(render.sharedMaterial.name.Length - material.name.Length > 1)
				{
					if(render.sharedMaterial.name[material.name.Length] == ' ')
					{
						if(!render.sharedMaterial.name.StartsWith(material.name))
						{
							needSet = true;
						}
					}
					else
					{
						needSet = true;
					}
				}
				else
				{
					needSet = true;
				}
			}

			if(needSet)
			{
				render.sharedMaterial = material;
			}
		}
	}

	static Material getMaterial (string texName, bool isUI)
	{
		string materialName = null;
		if(isUI)
		{
			materialName = texName + ResourcesEx.spriteSheetUiMaterialSuffix;
		}
		else
		{
			materialName = texName + ResourcesEx.spriteSheetMaterialSuffix;
		}

		Material material = null;
		System.WeakReference reference = null;
		bool isExist = materialMap.TryGetValue (materialName, out reference);
		if (!isExist || reference != null)
		{
			if (reference != null)
			{
				material = reference.Target as Material;
			}

			if (material == null)
			{
				string realTexName = texName;

                material = ResourcesEx.LoadAsset<Material>(ResourcesEx.getSheetDirName() + "/" + realTexName + "/" + materialName);
				if (material != null)
				{
					materialMap[materialName] = new System.WeakReference (material);
				}
				else
				{
					materialMap[materialName] = null;
				}
			}
		}
		return material;
	}

	public static Material getMaterial(Material oldMaterial, Sprite newSprite, bool isUI, out bool needSet)
	{
		if(newSprite == null)
		{
			needSet = true;
			return getBaseMaterial(isUI);
		}

		needSet = false;
		Material material = null;
		if(newSprite != null && oldMaterial != null)
		{
			if(oldMaterial.mainTexture == newSprite.texture)
			{
				if(isUI)
				{
					if(oldMaterial.name.EndsWith(ResourcesEx.spriteSheetUiMaterialSuffix))
					{
						return null;
					}
				}
				else
				{
					if(oldMaterial.name.EndsWith(ResourcesEx.spriteSheetMaterialSuffix))
					{
						return null;
					}
				}
			}
		}

		if(material == null && newSprite != null)
		{
			needSet = true;
			if(newSprite.isFromSpriteSheet())
			{
				string texName = newSprite.texture.name;
				material = getMaterial (texName, isUI);

				if(material != null && oldMaterial != null)
				{
					if(oldMaterial.name == material.name)
					{
						material = null;
						needSet = false;
					}
				}
			}
		}

		if(needSet && material == null)
		{
			material = getBaseMaterial(isUI);
		}
		return material;
	}
}

